// benchmark_lambda_vs_bind.cpp
#include <benchmark/benchmark.h>
#include <functional>

// 简单的二元函数，假装做点轻量工作
inline int add_ints(int a, int b) noexcept {
    return (a ^ b) + (a & b);
}

constexpr int kIterationsPerCall = 1 << 10;  // 每次基准里执行的调用次数

static void BM_DirectCall(benchmark::State& state) {
    for (auto _ : state) {
        int acc = 0;
        for (int i = 0; i < kIterationsPerCall; ++i) {
            benchmark::DoNotOptimize(acc = add_ints(i, acc));
        }
        benchmark::DoNotOptimize(acc);
    }
}

static void BM_LambdaCall(benchmark::State& state) {
    auto lambda = [](int a, int b) noexcept { return add_ints(a, b); };
    for (auto _ : state) {
        int acc = 0;
        for (int i = 0; i < kIterationsPerCall; ++i) {
            benchmark::DoNotOptimize(acc = lambda(i, acc));
        }
        benchmark::DoNotOptimize(acc);
    }
}

static void BM_BindCall(benchmark::State& state) {
    int acc = 0;
    auto bound = std::bind(add_ints, std::placeholders::_1, std::ref(acc));
    for (auto _ : state) {
        acc = 0;
        for (int i = 0; i < kIterationsPerCall; ++i) {
            benchmark::DoNotOptimize(acc = bound(i));
        }
        benchmark::DoNotOptimize(acc);
    }
}

// 也可以给 bind 额外加一组 “占位符 + 占位符” 以比较完全绑定
static void BM_BindCallPlaceholders(benchmark::State& state) {
    auto bound = std::bind(add_ints, std::placeholders::_1, std::placeholders::_2);
    for (auto _ : state) {
        int acc = 0;
        for (int i = 0; i < kIterationsPerCall; ++i) {
            benchmark::DoNotOptimize(acc = bound(i, acc));
        }
        benchmark::DoNotOptimize(acc);
    }
}

BENCHMARK(BM_DirectCall);
BENCHMARK(BM_LambdaCall);
BENCHMARK(BM_BindCall);
BENCHMARK(BM_BindCallPlaceholders);

BENCHMARK_MAIN();